package cn.yitun.chat.yitunserverrunsingleboot.chat.common.service.impl;

import cn.yitun.chat.yituncommonutil.YitunMD5Util;
import cn.yitun.chat.yituncommonutil.YitunMapUtil;
import cn.yitun.chat.yitunservercommonlib.constant.ServerConstant;
import cn.yitun.chat.yitunservercommonlib.dataentity.data.server.ServerAddress;
import cn.yitun.chat.yitunservercommonlib.dataentity.data.server.ServerData;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.UserDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserVo;
import cn.yitun.chat.yitunservercommonlib.enums.system.UserRoleTypeEnums;
import cn.yitun.chat.yitunservercommonlib.util.PinYinUtil;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverfilecore.config.FileServerConfig;
import cn.yitun.chat.yitunserverfilecore.manage.FileServerConfigManager;
import cn.yitun.chat.yitunserverimbase.dao.system.UserDao;
import cn.yitun.chat.yitunservermanagecore.general.manage.server.service.ServerService;
import cn.yitun.chat.yitunserverrunsingleboot.chat.common.box.ConfigBox;
import cn.yitun.chat.yitunserverrunsingleboot.chat.common.service.InitializerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class InitializerServiceImpl implements InitializerService {
	
	@Resource
	private UserDao userDAO;

	@Resource
	private ServerService serverService;

	@Resource
	private FileServerConfigManager fileServerConfigManager;

	@Override
	public void initialize() {
		// 初始化root用户
		initRootUser();
		// 初始化服务器地址
		initServerAddress();
		// 初始化文件地址
		initFileUrl();
	}
	
	/**
	 * 初始化超级管理员
	 */
	private void initRootUser(){
		UserDto userQuery = new UserDto();
		userQuery.setType(UserRoleTypeEnums.TYPE_ROOT.getType());
		List<UserVo> list = userDAO.listVO(YitunMapUtil.java2Map(userQuery, false) );
		if(list.isEmpty()){
			UserDto userDto = new UserDto();
			userDto.setCode(IdGen.uuid());
			userDto.setAccount("root");
			userDto.setPassword(YitunMD5Util.md5L32("123456"));
			userDto.setName("超级管理员");
			userDto.setType(UserRoleTypeEnums.TYPE_ROOT.getType());
			userDto.setNickname("超级管理员");
			userDto.setSimpleSpell(PinYinUtil.getFirstSpell(userDto.getName()));
			userDto.setSpell(PinYinUtil.getFullSpell(userDto.getName()));
			userDto.setCountry("中国");
			userDto.setProvince("北京");
			userDto.setCity("北京");
			userDto.setDistrict("东城区");
			userDto.setLiveAddress("东长安街1号");
			userDto.setUpdateBy(1l);
			userDto.setUpdateTime(System.currentTimeMillis());
			userDto.setCreateBy(1l);
			userDto.setCreateTime(System.currentTimeMillis());
			userDto.setRemark("root");
			userDAO.save(userDto);
		}
	}

	/**
	 * 初始化服务器地址
	 */
	private void initServerAddress() {
		String main = (ServerConstant.ServerType.main.value());
		String api = (ServerConstant.ServerType.api.value());
		String file = (ServerConstant.ServerType.file.value());
		String mode = (ServerConstant.ServerType.mode.value());
		// String video = (ServerConstant.ServerType.video.value());
		// String voice = (ServerConstant.ServerType.voice.value());

		List<ServerData> configServerDataList = new ArrayList<>();

//		String addressKey = "server.config.address";
//		String address = serverProperties.getServerAddress();

//		address = (YitunStringUtil.isEmpty(address)) ? YitunAddressUtil.getLocalHostIP() : address;

		String category = "";
		String key = "";
		String value = "";
		String httpServerProxy = ""; //http服务器代理名你

		category = ServerConstant.ServerAddressOrPort.CATEGORY_CONFIG_BASE.value();
		key = "server.config.enabled";
		String enabled = ConfigBox.get(category, key);

		if ("true".equals(enabled)) {


			ServerAddress serverMode = new ServerAddress(); //是否代理
			ServerAddress mainTcp = new ServerAddress(); //socket
			ServerAddress mainWebSocket = new ServerAddress(); //websocket
			ServerAddress mainHttp = new ServerAddress(); //http


			/******************************** mode start ********************************/

			category = ServerConstant.ServerAddressOrPort.CATEGORY_CONFIG_PROXY.value();

			key = ServerConstant.ServerAddressOrPort.SERVER_MODE.value();
//			key = "server.main.tcp.address";
			value = ConfigBox.get(category, key);
			serverMode.setEnabled(ServerConstant.ServerMode.PRO.value().equalsIgnoreCase(value) ? "1" : "0");
			List<ServerAddress> serverModeList = new ArrayList<>();
			serverModeList.add(serverMode);

			ServerData serverModeData = new ServerData();
			serverModeData.setCode(mode);
			serverModeData.setEnabled("1");
			serverModeData.setAddressList(serverModeList);

			/******************************** mode end ********************************


			/******************************** main start ********************************
			 * main
			 * 客户端使用到的主要路径在这里配置
			 */
			category = ServerConstant.ServerAddressOrPort.CATEGORY_PATH_CHAT.value();
//			category = "server.path.main";

			/**
			 * 聊天服务tcp
			 * socket连接时使用
			 */
			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_TCP_ADDRESS.value();
//			key = "chat.server.tcp.address";
			value = ConfigBox.get(category, key);
			mainTcp.setAddress(value);

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_TCP_PORT.value();
//			key = "chat.server.tcp.port";
			value = ConfigBox.get(category, key);
			mainTcp.setPort(Integer.parseInt(value));

			mainTcp.setProtocol(ServerConstant.Protocol.TCP.value());
			mainTcp.setAddressType(ServerConstant.AddressType.IPv4.value());
			mainTcp.setEnabled("1");

			/**
			 * #聊天服务的webSocket路径
			 * chat.server.websocket.path=ws://192.168.200.1:12020/oim/websocket
			 * websocket地址
			 */
			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_WEBSOCKET_ADDRESS.value();
//			key = "chat.server.websocket.address";
			value = ConfigBox.get(category, key);
			mainWebSocket.setAddress(value);

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_WEBSOCKET_PORT.value();
//			key = "chat.server.websocket.port";
			value = ConfigBox.get(category, key);
			mainWebSocket.setPort(Integer.parseInt(value));

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_WEBSOCKET_SUFFIX.value();
//			key = "chat.server.websocket.suffix";
			value = ConfigBox.get(category, key);
			mainWebSocket.setSuffix(value);

			mainWebSocket.setProtocol(ServerConstant.Protocol.WebSocket.value());
			mainWebSocket.setAddressType(ServerConstant.AddressType.URL.value());
			mainWebSocket.setEnabled("1");

			/**
			 * 聊天服务的http地址
			 * 客户端一些特殊请求将会使用此配置
			 */
			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_HTTP_ADDRESS.value();
//			key = "chat.server.http.address";
			value = ConfigBox.get(category, key);
			mainHttp.setAddress(value);

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_HTTP_PORT.value();
//			key = "chat.server.http.port";
			value = ConfigBox.get(category, key);
			mainHttp.setPort(Integer.parseInt(value));

			mainHttp.setProtocol(ServerConstant.Protocol.HTTP.value());
			mainHttp.setAddressType(ServerConstant.AddressType.URL.value());
			mainHttp.setEnabled("1");


			/**
			 * 代理服务名称
			 * 基于有路由代理如nginx等将会使用到此配置
			 * 需要与mode参数配合使用
			 */
			category = ServerConstant.ServerAddressOrPort.CATEGORY_CONFIG_PROXY.value();
			// 代理服务 各端口映射
			key = ServerConstant.ServerAddressOrPort.SERVER_PROXY.value();
//			key = "server.proxy";
			value = ConfigBox.get(category, key);
			httpServerProxy = value;
			mainHttp.setProxy(value);
			key = ServerConstant.ServerAddressOrPort.SERVER_CONFIG_CHAT_TCP_PROXY.value();
//			key = "server.config.chat.tcp.proxy";
			value = ConfigBox.get(category, key);
			mainTcp.setProxy(value);
			key = ServerConstant.ServerAddressOrPort.SERVER_CONFIG_CHAT_WEBSOCKET_PROXY.value();
//			key = "server.config.chat.websocket.proxy";
			value = ConfigBox.get(category, key);
			mainWebSocket.setProxy(value);

			List<ServerAddress> mainAddressList = new ArrayList<>();
			mainAddressList.add(mainTcp);
			mainAddressList.add(mainWebSocket);
			mainAddressList.add(mainHttp);

			ServerData mainServerData = new ServerData();
			mainServerData.setCode(main);
			mainServerData.setEnabled("1");
			mainServerData.setAddressList(mainAddressList);

			/******************************** main end ********************************/


			/******************************** api start ********************************/
			/**
			 * api服务地址
			 */
			ServerAddress apiHttp = new ServerAddress();
			category = ServerConstant.ServerAddressOrPort.CATEGORY_PATH_API.value();
//			category = "server.path.api";
			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_API_HTTP_ADDRESS.value();
//			key = "chat.server.api.http.address";
			value = ConfigBox.get(category, key);
			apiHttp.setAddress(value);

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_API_HTTP_PORT.value();
//			key = "chat.server.api.http.port";
			value = ConfigBox.get(category, key);
			apiHttp.setPort(Integer.parseInt(value));

			apiHttp.setProxy(httpServerProxy);
			apiHttp.setProtocol(ServerConstant.Protocol.HTTP.value());
			apiHttp.setAddressType(ServerConstant.AddressType.URL.value());
			apiHttp.setEnabled("1");

			List<ServerAddress> apiAddressList = new ArrayList<>();
			apiAddressList.add(apiHttp);

			ServerData apiServerData = new ServerData();
			apiServerData.setCode(api);
			apiServerData.setEnabled("1");
			apiServerData.setAddressList(apiAddressList);
			/**
			 * 文件服务地址
			 */
			// #文件服务地址
			// file.server.http.url=http://192.168.200.1:12000
			category = ServerConstant.ServerAddressOrPort.CATEGORY_PATH_FILE.value();
//			category = "server.path.file";

			ServerAddress fileHttp = new ServerAddress();

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_FILE_HTTP_ADDRESS.value();
//			key = "chat.server.file.http.address";
			value = ConfigBox.get(category, key);
			fileHttp.setAddress(value);

			key = ServerConstant.ServerAddressOrPort.CHAT_SERVER_FILE_HTTP_PORT.value();
//			key = "chat.server.file.http.port";
			value = ConfigBox.get(category, key);
			fileHttp.setPort(Integer.parseInt(value));

			fileHttp.setProxy(httpServerProxy);
			fileHttp.setProtocol(ServerConstant.Protocol.HTTP.value());
			fileHttp.setAddressType(ServerConstant.AddressType.URL.value());
			fileHttp.setEnabled("1");

			List<ServerAddress> fileAddressList = new ArrayList<>();
			fileAddressList.add(fileHttp);

			ServerData fileServerData = new ServerData();
			fileServerData.setCode(file);
			fileServerData.setEnabled("1");
			fileServerData.setAddressList(fileAddressList);

			configServerDataList.add(serverModeData);
			configServerDataList.add(mainServerData);
			configServerDataList.add(apiServerData);
			configServerDataList.add(fileServerData);

		}

		serverService.setConfigServerDataList(configServerDataList);
	}

	/**
	 * 初始化文件地址
	 */
	void initFileUrl() {
		FileServerConfig fileServerConfig = new FileServerConfig();

		String category = ServerConstant.ServerAddressOrPort.CATEGORY_CONFIG_FILE.value();

		String key = ServerConstant.ServerAddressOrPort.SERVER_CONFIG_FILE_UPLOAD_PATH.value();
		String value = ConfigBox.get(category, key);
		fileServerConfig.setPath(value);

		key = ServerConstant.ServerAddressOrPort.SERVER_CONFIG_FILE_REQUEST_PATH.value();
		value = ConfigBox.get(category, key);
		fileServerConfig.setUrl(value);

		fileServerConfigManager.setFileServerConfig(fileServerConfig);
	}

}
